﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

using StateSharp;

namespace TestForm
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// 执行动作枚举。
        /// </summary>
        enum OptCode
        {
            /// <summary>
            /// 开始。
            /// </summary>
            Start,
            /// <summary>
            /// 关闭。
            /// </summary>
            Close,
            /// <summary>
            /// 暂停。
            /// </summary>
            Pause,
            /// <summary>
            /// 继续。
            /// </summary>
            Continue,
        }
        Timer m_timer; // 定时器。
        Stopwatch m_watch; // 计时器。
        State<OptCode> m_start; // 开始。
        State<OptCode> m_continue; // 继续。
        State<OptCode> m_pause; // 暂停。
        State<OptCode> m_close; // 关闭。
        Context<OptCode> m_context; // 上下文。
        int m_timeTmp; // 时间。
        int m_currentTime; // 当前时间。

        public Form1()
        {
            InitializeComponent();
            m_timer = new Timer();
            m_timer.Interval = 50;
            m_timer.Tick += new EventHandler(TimerTick);
            m_watch = new Stopwatch();
            m_timeTmp = 0;

            InitState();
        }
        /// <summary>
        /// 初始化状态。 总共三个状态，四种转换。
        /// </summary>
        private void InitState()
        {
            m_start = new State<OptCode>();
            m_pause = new State<OptCode>();
            m_close = new State<OptCode>();
            m_continue = new State<OptCode>();

            m_start.Exec = DoStart;
            m_pause.Exec = DoPause;
            m_close.Exec = DoClose;
            m_continue.Exec = DoContinue;
            // 关闭的状态转换。
            m_close.AddTransition(OptCode.Start, m_start);
            // 启动状态转换。
            m_start.AddTransition(OptCode.Pause, m_pause);
            m_start.AddTransition(OptCode.Close, m_close);
            m_start.AddTransition(OptCode.Start, m_start);
            // 启动状态转换。
            m_continue.AddTransition(OptCode.Pause, m_pause);
            m_continue.AddTransition(OptCode.Close, m_close);
            m_continue.AddTransition(OptCode.Start, m_start);
            // 暂停状态转换。
            m_pause.AddTransition(OptCode.Start, m_start);
            m_pause.AddTransition(OptCode.Continue, m_continue);
            m_pause.AddTransition(OptCode.Close, m_close);

            m_context = new Context<OptCode>();
            m_context.InitState(m_close);
            m_context.Start();
        }

        /// <summary>
        /// 执行关闭。
        /// </summary>
        /// <param name="code"></param>
        void DoClose(OptCode code)
        {
            m_timer.Stop();
            m_watch.Stop();
            SetTime(0);

            btnPause.Enabled = false;
            btnContinue.Enabled = false;
        }
        /// <summary>
        /// 执行暂停。
        /// </summary>
        /// <param name="code"></param>
        void DoPause(OptCode code)
        {
            m_timer.Stop();
            m_watch.Stop(); 
            m_timeTmp = m_currentTime;

            btnPause.Enabled = false;
            btnContinue.Enabled = true;
        }
        /// <summary>
        /// 执行开始。
        /// </summary>
        /// <param name="code"></param>
        void DoStart(OptCode code)
        {
            m_timeTmp =0;
            TimeStart();
        }

        private void TimeStart()
        {
            m_timer.Start();
            m_watch.Restart();

            btnPause.Enabled = true;
            btnContinue.Enabled = false;
        }
        /// <summary>
        /// 设置时间显示。
        /// </summary>
        /// <param name="value"></param>
        void SetTime(int value)
        {
            m_currentTime = value;
            labTime.Text = ((float)value / 1000.0f).ToString("0.0");
        }
        /// <summary>
        /// 定时器。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void TimerTick(object sender, EventArgs e)
        {
            SetTime(m_timeTmp + (int)(m_watch.ElapsedMilliseconds));
        }
        /// <summary>
        /// 启动按钮。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            m_context.DoTransition(OptCode.Start);
        }
        /// <summary>
        /// 暂停按钮。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPause_Click(object sender, EventArgs e)
        {
            m_context.DoTransition(OptCode.Pause);
        }
        /// <summary>
        /// 关闭按钮。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            m_context.DoTransition(OptCode.Close);
        }
        /// <summary>
        /// 继续按钮。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnContinue_Click(object sender, EventArgs e)
        {
            m_context.DoTransition(OptCode.Continue);
        }
        /// <summary>
        /// 继续开始。
        /// </summary>
        /// <param name="code"></param>
        void DoContinue(OptCode code)
        {
            TimeStart();
        }
    }
}
